package com.zc.framework.spring.aspect;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 执行 cost ，及内存消耗
 * Created by zc on 2016/11/7.
 */
@Component
@Aspect
public class ControllerAspect {
    private static Logger logger = LogManager.getLogger(ControllerAspect.class);


    /**
     * 切面
     */
    private final String POINT_CUT = "execution(* com.zc.app.*.controller.*.*(..))";

    @Pointcut(POINT_CUT)
    private void pointcut() {

    }

    @AfterThrowing(value = POINT_CUT, throwing = "e")
    public void afterThrowing(Throwable e) {
        logger.error("afterThrowing: " + e.getMessage(), e);
    }

    /**
     * @功能描述: 打印Controller方法的执行时间
     * @创建日期: 2016年11月2日 上午11:44:11
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINT_CUT)
    public Object around(ProceedingJoinPoint proceedingJoinPoint)
            throws Throwable {
        String className = proceedingJoinPoint.getTarget().getClass().getName();
        String methodName = proceedingJoinPoint.getSignature().getName();
        Long begin = System.currentTimeMillis();
        Long beginMemory = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
        StringBuilder log = new StringBuilder(className+"@"+methodName);
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Exception e) {
            logger.error(log + e.getMessage(), e);
        }
        Long end = System.currentTimeMillis();
        Long endMemory = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
        log.append(" 执行时间: ").append(end - begin).append("ms");
        log.append(" 消耗内存: ").append(endMemory - beginMemory).append("Byte");
        logger.info(log);
        return result;
    }

}
